package com.apache.funds.common;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;

import com.apache.tools.StrUtil;

public class NumberUtil {

	public static int doNumberNull(Integer n) {
		int number = 0;
		if (n != null) {
			return n;
		} else {
			return number;
		}
	}

	public static Long doNumberNull(Long n) {
		Long number = 0L;
		if (n != null) {
			return n;
		} else {
			return number;
		}
	}

	public static Double doNumberNull(Double n) {
		Double number = 0d;
		if (n != null) {
			return n;
		} else {
			return number;
		}
	}

	/**
	 * 比较2个数的大小
	 * @param d1
	 * @param d2
	 * @return 返回最大的值
	 */
	public static double getMaxNum(double d1, double d2) {
		return d1 > d2 ? d1 : d2;
	}

	/**
	 * 比较2个数的大小
	 * @param d1
	 * @param d2
	 * @return 返回最小的值
	 */
	public static double getMinNum(double d1, double d2) {
		return d1 < d2 ? d1 : d2;
	}

	/**
	 * 获取格式化后的数字
	 * @param number 待转换的数字
	 * @param len 指定转换后小数位数
	 * @param isdf 是否带千分位分隔符
	 * @return
	 */
	public static String getDecimalFormatNum(double number, int len, boolean isdf) {
		String result = String.valueOf(number);
		boolean isf = false;
		if (number < 0) {
			number = Math.abs(number);
			isf = true;
		}
		//	if (number>0) {
		String df = "###,###,###,###,##0";
		if (!isdf) {
			df = df.replaceAll(",", "");
		}
		if (len > 0) {
			df += ".";
			for (int i = 0; i < len; i++) {
				df += "0";
			}
		}
		DecimalFormat dfNew = new DecimalFormat(df);
		result = dfNew.format(number);
		//}
		if (isf) {
			result = "-" + result;
		}
		return result;
	}

	/**
	 * 将数据库金额1000,装换为页面显示的10块钱<br>
	 * 为了不让数据库存小数,在保存的时候统一*100,所以要先除100在页面显示
	 * @param  String money 1000
	 * @return String 10.00
	 */
	public static String formatMoney(String money) {
		DecimalFormat df = new DecimalFormat("########0.00");
		if (StrUtil.isNull(money))
			money = "0";
		return df.format(div(Double.parseDouble(money), 100, 2));
	}

	/**
	 * 将页面金额10,装换为数据库保存的1000<br>
	 * 为了不让数据库存小数,在保存的时候统一*100,所以要先乘100在保存数据库
	 * @param  Double money 10
	 * @return Long 1000
	 */
	public static Long formatMoneyIN(Double money) {
		if (money == null || money == 0) {
			money = 0D;
		}
		money = mul(money, 100, 2);
		return money.longValue();
	}

	/** 
	* 提供精确的加法运算。 
	*  (NumberUtils.add工具类里面的方法不好使别用了,真坑爹)
	* @param v1 
	*            被加数 
	* @param v2 
	*            加数 
	*  @param scale
	*      运算后返回值保留的小数位数
	* @return 两个参数的和 
	*/
	public static double add(double v1, double v2, int scale) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return round(b1.add(b2).doubleValue(), scale);
	}

	/**
	 * 浮点数精确减法运算
	 * 
	 * @param v1,v2
	 *            进行运算的参数
	 * @param scale
	 *            运算后返回值保留的小数位数
	 * 
	 * @return 两个参数按照精度进行减法运算后的结果
	 */
	public static double sub(double v1, double v2, int scale) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return round(b1.subtract(b2).doubleValue(), scale);
	}

	/**
	 * 加法 v1-v2
	 */
	public static long add(long v1, long v2) {
		BigDecimal b1 = new BigDecimal(Long.toString(v1));
		BigDecimal b2 = new BigDecimal(Long.toString(v2));
		return b1.add(b2).longValue();
	}

	/**
	 * 减法 v1-v2
	 */
	public static long sub(long v1, long v2) {
		BigDecimal b1 = new BigDecimal(Long.toString(v1));
		BigDecimal b2 = new BigDecimal(Long.toString(v2));
		return b1.subtract(b2).longValue();
	}

	/**
	 * 浮点数精确乘法运算
	 * 
	 * @param v1,v2
	 *            进行运算的参数
	 * @param scale
	 *            运算后返回值保留的小数位数
	 * 
	 * @return 两个参数按照精度进行乘法运算后的结果
	 */
	public static double mul(double v1, double v2, int scale) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return round(b1.multiply(b2).doubleValue(), scale);
	}

	/**
	 * 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指
	 * 定精度，以后的数字四舍五入。
	 * @param v1 被除数
	 * @param v2 除数
	 * @param scale 表示表示需要精确到小数点以后几位。
	 * @return 两个参数的商
	 */
	public static double div(double v1, double v2, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 浮点数精确四舍五入
	 * 
	 * @param v
	 *            进行运算的参数
	 * @param scale
	 *            运算后返回值保留的小数位数
	 * 
	 * @return 按照精度进行四舍五入后的结果
	 */
	public static double round(double v, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b = new BigDecimal(Double.toString(v));
		BigDecimal one = new BigDecimal("1");
		return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/** 
	* 将double转换为long类型 
	*  @param double
	* @return long
	*/

	public static long doubleToLong(double num) {
		return new Double(num).longValue();
	}

	/** 
	 * 获取百分比
	 *
	 *   @param   p1
	 *   @param   p2
	 *   @return
	 */
	public static String percent(double p1, double p2) {
		NumberFormat nf = NumberFormat.getPercentInstance();
		nf.setMinimumFractionDigits(2);
		if (p2 == 0) {
			return nf.format(0);
		}
		double p3 = p1 / p2;
		return nf.format(p3);
	}

	/**
	 * 浮点数精确【比较两个浮点数是否相等】
	 * @param v1 进行运算的参数1
	 * @param v2 进行运算的参数2
	 * @param scale 运算后返回值保留的小数位数
	 * @return  比较是否相等的结果
	 */
	public static boolean equal(double v1, double v2, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal V1 = new BigDecimal(Double.toString(v1)).divide(new BigDecimal(1), scale, BigDecimal.ROUND_HALF_UP);
		BigDecimal V2 = new BigDecimal(Double.toString(v2)).divide(new BigDecimal(1), scale, BigDecimal.ROUND_HALF_UP);

		return V1.equals(V2);
	}

	/**
	* 取出两个数中距离第三个最近的数
	* @param num1 要比较数1
	* @param num2 要比较数2
	* @param num3 被比较数
	* @return 如（10,14,13）则返回14，如（10,14,12）则返回12
	*/
	public static Long getABS(Long num1, Long num2, Long num3) {
		System.out.println("数1=[" + num1 + "],数2=[" + num2 + "],比较数=[" + num3 + "]--取出此两个数中距离第三个比较数最近的数");
		if (Math.abs(num1 - num3) < Math.abs(num2 - num3)) {
			return num1;
		}
		if (Math.abs(num1 - num3) == Math.abs(num2 - num3)) {
			return num3;
		} else {
			return num2;
		}
	}

}
